package com.asiainfo.complier.codemanger;

import java.awt.Component;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.swing.Icon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JWindow;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.filechooser.FileView;
import javax.swing.undo.UndoManager;

import com.asiainfo.complier.action.ComplierAction;
import com.asiainfo.complier.common.CodeInfo;
import com.asiainfo.complier.conf.ConfManager;
import com.asiainfo.complier.conf.SysSetting;
import com.asiainfo.complier.editor.CoderEditor;
import com.asiainfo.complier.editor.ICallBack;
import com.asiainfo.complier.editor.ToolTipJTabbedPane;
import com.asiainfo.complier.helper.FileHelper;
import com.asiainfo.complier.helper.StringHelper;
import com.asiainfo.complier.helper.UIHelper;
import com.asiainfo.complier.ui.StatusBarItem;

public class CodeManager {

	private ToolTipJTabbedPane editorPanel = null;

	/**
	 * get instance
	 * 
	 * @param _editorPanel
	 * @return
	 */
	public CodeManager(ToolTipJTabbedPane _editorPanel) {

		this.editorPanel = _editorPanel;
		SysSetting.initSetting();

	}

	/**
	 * add a new code path
	 * 
	 * @param filePath
	 */
	public CoderEditor addCoderPane(String filePath, String fileText,
			final StatusBarItem item) {
		int size = editorPanel.getTabCount();

		boolean isFind = false;

		for (int i = 0; i < size; i++) {

			CoderEditor codePane = (CoderEditor) editorPanel.getComponent(i);

			CodeInfo info = codePane.getCodeInfo();

			if (filePath != null && filePath.equals(info.getFilePath())) {
				isFind = true;
				editorPanel.setSelectedIndex(i);
				return codePane;
			}

		}

		if (!isFind) {
			CodeInfo info = new CodeInfo();
			info.setFilePath(filePath);
			CoderEditor editor = new CoderEditor(info);
			if (!StringHelper.isNullOrEmpty(fileText)) {
				editor.getEditor().initText(fileText);

			}
			if (SysSetting.SHOW_LINE.equals("true"))
				editor.setShowLineNumber(true);
			else {
				editor.setShowLineNumber(false);
			}
			if (SysSetting.HIGHTER_LINE.equals("true"))
				editor.setShowLineHighter(true);
			else
				editor.setShowLineHighter(false);
			editorPanel.addTab(info.toString(),
					UIHelper.getImageIco("com/asiainfo/images/class.png"),
					editor, info.getFilePath());

			editorPanel.setSelectedIndex(editorPanel.getTabCount() - 1);
			editor.setCaretCallBack(new ICallBack() {

				public void doWOrk(Object obj) {
					if (obj != null)
						item.setText(obj.toString());
				}
			});

			editor.getEditor().getDocument()
					.addDocumentListener(new DocumentListener() {

						public void removeUpdate(DocumentEvent e) {
							updateModifyTitile();
						}

						public void insertUpdate(DocumentEvent e) {
							updateModifyTitile();
						}

						public void changedUpdate(DocumentEvent e) {
							updateModifyTitile();
						}
					});
			return editor;

		}
		return null;
	}

	private void updateModifyTitile() {
		int i = editorPanel.getSelectedIndex();
		if (i >= 0) {
			String name = editorPanel.getTitleAt(i);
			name = name.replace("*", "");
			editorPanel.setTitleAt(i, "<html><font color='red'>*</font>" + name
					+ "</html>");
		}
	}

	/**
	 * get active code panel
	 * 
	 * @return
	 */

	public CoderEditor getActiveCoderEditor() {
		int i = editorPanel.getSelectedIndex();
		if (i >= 0) {
			CoderEditor codePane = (CoderEditor) editorPanel.getComponent(i);

			return codePane;
		} else {

			return null;
		}
	}

	/**
	 * getActiveEditorPath
	 * 
	 * @return
	 */
	public String getActiveEditorPath() {
		CoderEditor editor = getActiveCoderEditor();
		if (editor == null)
			return "";
		CodeInfo info = editor.getCodeInfo();
		if (info.getFilePath() != null) {
			return info.getFilePath();
		} else {
			return "";
		}
	}

	/**
	 * save file
	 * 
	 * @param c
	 * @throws Exception
	 */
	public void save(Component c) throws Exception {
		CoderEditor editor = getActiveCoderEditor();
		if (editor == null)
			return;
		CodeInfo info = editor.getCodeInfo();
		if (info.getFilePath() != null) {
			FileHelper.write2File(info.getFilePath(), editor.getText());
			int index = editorPanel.getSelectedIndex();
			editorPanel.setTitleAt(index, info.toString());
		} else {
			saveAs(c);
		}

	}

	/**
	 * save as file
	 * 
	 * @param c
	 * @throws Exception
	 */
	private static String lastPath = ".";

	public void saveAs(Component c) throws Exception {
		JFileChooser chooser = new JFileChooser(lastPath);

		CoderEditor editor = getActiveCoderEditor();
		if (null == editor)
			return;
		int ret = chooser.showSaveDialog(c);
		if (ret == JFileChooser.APPROVE_OPTION) {
			lastPath = chooser.getSelectedFile().getParent();
			String filePath = chooser.getSelectedFile().getCanonicalPath();

			chooser.setFileFilter(new JavaFileFilter());
			CodeInfo info = new CodeInfo();
			info.setFilePath(filePath);
			FileHelper.write2File(filePath, editor.getText());
			int index = editorPanel.getSelectedIndex();
			editorPanel.setTitleAt(index, info.toString());

			editor.setCodeInfo(info);
			editorPanel.setSelectedIndex(-1);
			editorPanel.setSelectedIndex(index);

		}
	}

	public void close() {

		int index = editorPanel.getSelectedIndex();
		if (index >= 0)
			editorPanel.removeTabAt(index);
	}

	public void closeAll() {

		editorPanel.removeAll();
	}

	public String getPacketName() {
		String allText = getActiveCoderEditor().getText();
		String packet = "package";
		int index = allText.indexOf(packet);
		if (index != -1) {
			int endIndex = allText.indexOf(";", index + packet.length());
			if (endIndex != -1) {
				return allText.substring(index + packet.length(), endIndex)
						.trim();
			} else {
				return "";
			}
		} else {
			return "";
		}

	}

	/**
	 * get file Name
	 * 
	 * @return
	 */

	public String getFiletName() {

		CoderEditor editor = getActiveCoderEditor();
		if (editor == null)
			return "";
		CodeInfo info = editor.getCodeInfo();
		return FileHelper.getFileName(info.getFilePath());
	}

	public void openFile(JFrame c, StatusBarItem lbLineStatusInfo) {
		CoderEditor editor = getActiveCoderEditor();
		if (null != editor) {
			String path = editor.getCodeInfo().getFilePath();
			if (path != null) {
				String parentDir = new File(path).getParent();
				if (null != parentDir)
					lastPath = parentDir;
			}
		}
		JFileChooser chooser = new JFileChooser(lastPath);
		chooser.setFileView(new FileView() {
			public Icon getIcon(File f) {
				if (f.isFile())
					return UIHelper.getImageIco("com/asiainfo/images/java.png");
				else {
					return UIHelper.getImageIco("com/asiainfo/images/dir.png");
				}
			}

		});
		chooser.setMultiSelectionEnabled(true);
		chooser.setFileFilter(new JavaFileFilter());
		int ret = chooser.showOpenDialog(c);
		if (ret == JFileChooser.OPEN_DIALOG) {

			try {

				File[] files = chooser.getSelectedFiles();
				for (File file : files) {
					lastPath = file.getParent();
					String filePath = file.getAbsolutePath();
					String fileText = FileHelper.readFullText(file
							.getAbsolutePath());
					addCoderPane(filePath, fileText, lbLineStatusInfo);
				}

			} catch (IOException ex) {

				ex.printStackTrace();
			}
		}
	}

	public void closeButThis() {
		ArrayList<CoderEditor> list = new ArrayList<CoderEditor>();
		CoderEditor curEditor = getActiveCoderEditor();
		int size = editorPanel.getTabCount();
		for (int i = 0; i < size; i++) {
			CoderEditor editor = (CoderEditor) editorPanel.getComponent(i);
			if (!editor.equals(curEditor)) {
				list.add(editor);
			}
		}
		for (CoderEditor coderEditor : list) {
			editorPanel.remove(coderEditor);
		}

	}

	public void openDir() {
		CoderEditor editor = getActiveCoderEditor();
		if (null == editor)
			return;
		CodeInfo info = editor.getCodeInfo();

		if (info != null)
			if (!StringHelper.isNullOrEmpty(info.getFilePath()))
				ComplierAction.execute("explorer /n,/select,\""
						+ info.getFilePath() + "  \"");

	}

	public void openOutPutDir() {
		CoderEditor editor = getActiveCoderEditor();
		if (null == editor)
			return;
		if (SysSetting.OUTPUT_PATH != null)

			ComplierAction.execute("explorer /n,\"" + SysSetting.OUTPUT_PATH
					+ "  \"");

	}

	/**
	 * @param
	 * @param item
	 */

	public void initConfFile(StatusBarItem item, JFrame fJFrame) {
		ArrayList<String> fileList = ConfManager.getConfFile();
		for (String str : fileList) {
			fJFrame.setTitle("load file ... " + str);
			String fileText;
			try {
				fileText = FileHelper.readFullText(str);
				addCoderPane(str, fileText, item);
			} catch (IOException e) {

				e.printStackTrace();
			}

		}
	}

	/***
     *
     */
	public void saveConfFile() {
		int size = editorPanel.getTabCount();
		ArrayList<String> fileList = new ArrayList<String>();
		for (int i = 0; i < size; i++) {
			CoderEditor codePane = (CoderEditor) editorPanel.getComponent(i);
			if (codePane.getCodeInfo() != null) {
				if (!StringHelper.isNullOrEmpty(codePane.getCodeInfo()
						.getFilePath())) {

					fileList.add(codePane.getCodeInfo().getFilePath());

				}
			}
		}
		ConfManager.write2Conf(fileList);
	}

	public void redo() {
		UndoManager edit = getActiveCoderEditor().getActiveEditor()
				.getUndoManager();
		if (edit.canRedo())
			edit.redo();
	}

	public void undo() {
		UndoManager edit = getActiveCoderEditor().getActiveEditor()
				.getUndoManager();
		if (edit.canUndo())
			edit.undo();
	}

	public void setParentWindow(JFrame frame) {
	}

	static JWindow window;

}
